﻿using PacketRush.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace PacketRush.Core.Test
{
    
    
    /// <summary>
    ///This is a test class for DataReaderTest and is intended
    ///to contain all DataReaderTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DataReaderAndWriterTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for DataReader
        ///</summary>
        [TestMethod()]
        public void ReadTest()
        {
            PacketWriter writer = GetMockDataWriter();

            Packet packet = writer.ToPacket();

            PacketReader reader = new PacketReader();
            reader.RawPacket = packet.Data;

            // Make sure the mock data is correct
            ValidateMockData(reader);
        }

        /// <summary>
        /// Uses the DataReader to read the mock data asserting the correct values
        /// </summary>
        /// <param name="reader"></param>
        private static void ValidateMockData(PacketReader reader)
        {
            Assert.AreEqual(byte.MaxValue, reader.ReadByte());

            // Compare the bytes like this :|
            byte[] bytesRead = reader.ReadBytes(6);
            byte[] bytesToCompare = new byte[] { 1, 2, 4, 8, 16, 32 };
            for (int i = 0; i < bytesToCompare.Length; i++)
            {
                Assert.AreEqual(bytesToCompare[i], bytesRead[i]);

            }

            Assert.AreEqual(char.MaxValue, reader.ReadChar());
            Assert.AreEqual(double.MaxValue, reader.ReadDouble());
            Assert.AreEqual("Hello, World", reader.ReadString(System.Text.Encoding.UTF8));
            Assert.AreEqual(float.MaxValue, reader.ReadSingle());
            Assert.AreEqual(int.MaxValue, reader.ReadInt32());
            Assert.AreEqual(long.MaxValue, reader.ReadInt64());
            Assert.AreEqual(short.MaxValue, reader.ReadInt16());
            Assert.AreEqual(uint.MaxValue, reader.ReadUInt32());
            Assert.AreEqual(ulong.MaxValue, reader.ReadUInt64());
            Assert.AreEqual(ushort.MaxValue, reader.ReadUInt16());
            Assert.AreEqual("Hello, World!£$%^**())_+6írd÷òß", reader.ReadString(System.Text.Encoding.UTF8));
        }

        /// <summary>
        /// Reads the data written by the mock writer, resets the writer, writes something different and reads again
        /// </summary>
        [TestMethod()]
        public void Read_Then_Clear_Writer_Then_Write_More_Then_Read_Again_Test()
        {
            PacketWriter writer = GetMockDataWriter();

            Packet packet = writer.ToPacket();

            PacketReader reader = new PacketReader();
            reader.RawPacket = packet.Data;

            // Make sure the mock data is correct
            ValidateMockData(reader);

            for (int i = 0; i < 20; i++)
            {

                // reset the writer
                writer.Reset();

                writer.Write("hello world", System.Text.Encoding.UTF8);
                writer.Write(12.25f);
                writer.Write("hallo, welt", System.Text.Encoding.UTF8);

                Packet anotherPacket = writer.ToPacket();

                reader.RawPacket = anotherPacket;

                Assert.AreEqual("hello world", reader.ReadString(System.Text.Encoding.UTF8));
                Assert.AreEqual(12.25f, reader.ReadSingle());
                Assert.AreEqual("hallo, welt", reader.ReadString(System.Text.Encoding.UTF8));
            }
        }

        /// <summary>
        /// Gets a DataWriter pre-populated with known test data
        /// </summary>
        private PacketWriter GetMockDataWriter()
        {
            PacketWriter writer = new PacketWriter();
            writer.Write(byte.MaxValue);
            writer.Write(new byte[] { 1, 2, 4, 8, 16, 32 });
            writer.Write(char.MaxValue);
            writer.Write(double.MaxValue);
            writer.Write("Hello, World", System.Text.Encoding.UTF8);
            writer.Write(float.MaxValue);
            writer.Write(int.MaxValue);
            writer.Write(long.MaxValue);
            writer.Write(short.MaxValue);
            writer.Write(uint.MaxValue);
            writer.Write(ulong.MaxValue);
            writer.Write(ushort.MaxValue);
            writer.Write("Hello, World!£$%^**())_+6írd÷òß", System.Text.Encoding.UTF8);

            return writer;
        }
    }
}
